<?php
/**
 * 功能点
 * milloc
 */
namespace app\models\db;

use yii\db\ActiveRecord;
use app\librarys\Tools;
use app\models\FunctionPointExt;

class FunctionPoint extends ActiveRecord
{
	const IS_DELETED_NO = 0;
	const IS_DELETED_YES = 1;
	const PARENT_ID_ROOT = '0';

	public static function tableName()
	{
		return 't_function_point';
	}

	public function beforeSave($insert)
	{
		if ($this->isNewRecord) {
			$this->create_datetime = date('Y-m-d H:i:s');
			$this->is_deleted = self::IS_DELETED_NO;
			$this->parent_id = isset($this->parent_id) ? $this->parent_id : self::PARENT_ID_ROOT;
			$this->id = Tools::db_uuid();
		} else {
			$this->modify_datetime = date('Y-m-d H:i:s');
		}
		return parent::beforeSave($insert);
	}

	public function rules()
	{
		return [
			[['name'], 'required',  'message' => '信息不能为空', 'when' => function () {
				return $this->isNewRecord;
			}],
			['description', 'string'],
			['name', 'string', 'max' => 255, 'message' => '名称长度应小于255'],
			['controller', 'validateController', 'message' => '控制器不存在'],
			['action', 'validateAction', 'message' => '动作不存在', 'when' => function () {
				return $this->validateController($this->controller);
			}],
			['parent_id', 'exist', 'targetAttribute' => 'id', 'message' => '父级不存在', 'when' => function () {
				return $this->parent_id;
			}],
		];
	}

	public function attributeLabels()
	{
		return [
			'id' => 'ID',
			'name' => '名称',
			'description' => '描述',
			'controller' => '控制器',
			'action' => '动作',
			'parent_id' => '父级功能',
			'is_deleted' => '是否删除',
			'create_datetime' => '创建时间',
			'modify_datetime' => '修改时间',
		];
	}

	public function validateController($attr, $params = [])
	{
		$controllerList = FunctionPointExt::getControllerList();
		return in_array($attr, $controllerList);
	}

	public function validateAction($attr, $params = [])
	{
		$actionList = FunctionPointExt::getActionList($this->controller);
		return in_array($attr, $actionList);
	}

	/**
	 * 递归删除
	 * todo
	 * 删除相关的role_function_point_relation中的记录
	 * @param  object $functionPoint AR对象
	 * @return bool
	 * @author milloc
	 * @date   2018-04-24
	 */
	public function recurseDeleteFunctionPoint($functionPoint = null)
	{
		if (!$functionPoint) {
			return true;
		}
		$functionPoint->is_deleted = self::IS_DELETED_YES;
		$res = $functionPoint->save();
		$child = self::find()->where(['parent_id' => $functionPoint->id, 'is_deleted' => self::IS_DELETED_NO])->all();
		
		foreach ($child as $item) {
			$res = $res && self::recurseDeleteFunctionPoint($item);
		}

		return $res;
	}

	/**
	 * 递归删除功能点
	 * 事务
	 * @return bool
	 * @author milloc
	 * @date   2018-04-24
	 */
	public function deleteFunctionPoint()
	{
		if ($this->isNewRecord) {
			return false;
		}
		$funPoint = $this;
		$res = false;
		$this->getDb()->transaction(function () use ($funPoint, &$res) {
			$res = $funPoint->recurseDeleteFunctionPoint($funPoint);
			if ($res === false) {
				throw new \Exception;
			}
		});
		return $res;
	}
}